module ziyi{
    export class FindPath{
        private catchFlag:boolean=false;
        private row:number=4;
        private col:number=4;
        private map:Array<Array<number>>=new Array<Array<number>>();
        private isObstacle:Array<Array<number>>=new Array<Array<number>>();;
        private changeFlag:number;
        public constructor(){
            for(let i:number=0;i<9;i++){
                let tmp:Array<number>=new Array<number>();
                this.map.push(tmp);
                for(let j:number=0;j<9;j++){
                    this.map[i].push(0);
                }
            }
            this.initRandomObs();
        }
        public setRowCol(i:number,j:number){
            this.row=i;
            this.col=j;
        }
        private initRandomObs(){
            for(let i:number=0;i<9;i++){
                let tmp:Array<number>=new Array<number>();
                this.isObstacle.push(tmp);
                for(let j:number=0;j<9;j++){
                    this.isObstacle[i].push(0);
                }
            }
            //在中心点方圆3步内(相对于矩阵而非真实排列)随机设置五个障碍点
            for(let i:number=0;i<5;i++){
                var x:number=Math.ceil(Math.random()*3-1);
                var y:number=Math.ceil(Math.random()*3-1);
                if(x==0&&y==0){
                    i=i-1;
                }else{
                    this.isObstacle[4+x][4+y]=1;//障碍点设置
                }
            }
            //在图中随机选取8个位置设置障碍点
            for(let i:number=0;i<8;i++){
                var x:number=Math.ceil(Math.random()*9-1);
                var y:number=Math.ceil(Math.random()*9-1);
                if((x==4&&y==4)||this.isObstacle[x][y]==1)
                {
                    i=i-1;
                }
                else{
                    this.isObstacle[x][y]=1;
                }
            }
        }
        public setObs(i:number,j:number):void{
            this.isObstacle[i][j]=1;
        }
        public ifObs(i:number,j:number):boolean{
            if(this.isObstacle[i][j]==1){
                return true;
            }
            return false;
        }
        private initMap():void{//初始化map图，将边缘点设置为1，正常点设置为0，障碍点设置为-1
            for(let i:number=0;i<9;i++){
                for(let j:number=0;j<9;j++){
                    this.map[i][j]=0;
                }
            }
            this.changeFlag=0;
            for(let i:number=0;i<9;i++){
                for(let j:number=0;j<9;j++){
                    if(this.isObstacle[i][j]==1)
                    {
                        this.map[i][j]=-1;
                    }
                }
            }
            for(let i:number=0;i<9;i++){
                if(this.isObstacle[i][0]==0){
                    this.map[i][0]=1;
                }
                if(this.isObstacle[i][8]==0){
                    this.map[i][8]=1;
                }
                if(this.isObstacle[8][i]==0){
                    this.map[8][i]=1;
                }
                if(this.isObstacle[0][i]==0){
                    this.map[0][i]=1;
                }
            }
        }
        public setColandRow(i:number,j:number){
            this.row=i;
            this.col=j;
        }
        private recurShortest():void{//回溯进行map最短距离的更新
            this.changeFlag=0;
            for(let i:number=1;i<8;i++){
                for(let j:number=1;j<8;j++){
                    //上
                    if(this.map[i][j-1]>0&&(this.map[i][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
                        this.changeFlag=1;
                        this.map[i][j]=this.map[i][j-1]+1;
                    }
                    //下
                    if(this.map[i][j+1]>0&&(this.map[i][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
                        this.changeFlag=1;
                        this.map[i][j]=this.map[i][j+1]+1;
                    }
                    //左
                    if(this.map[i-1][j]>0&&(this.map[i-1][j]<this.map[i][j]-1||this.map[i][j]==0)){
                        this.changeFlag=1;
                        this.map[i][j]=this.map[i-1][j]+1;
                    }
                    //右
                    if(this.map[i+1][j]>0&&(this.map[i+1][j]<this.map[i][j]-1||this.map[i][j]==0)){
                        this.changeFlag=1;
                        this.map[i][j]=this.map[i+1][j]+1;
                    }
                    if(i%2==0){
                        //奇数行,左上(i-1,j-1)左下(i+1,j-1)
                        //左上
                        if(this.map[i-1][j-1]>0&&(this.map[i-1][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
                            this.changeFlag=1;
                            this.map[i][j]=this.map[i-1][j-1]+1;
                        }
                        //左下
                        if(this.map[i+1][j-1]>0&&(this.map[i+1][j-1]<this.map[i][j]-1||this.map[i][j]==0)){
                            this.changeFlag=1;
                            this.map[i][j]=this.map[i+1][j-1]+1;
                        }
                    }else{
                        //偶数行，右上(i-1,j+1)右下(i+1,j+1)
                        //右上
                        if(this.map[i-1][j+1]>0&&(this.map[i-1][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
                            this.changeFlag=1;
                            this.map[i][j]=this.map[i-1][j+1]+1;
                        }
                        //右下
                        if(this.map[i+1][j+1]>0&&(this.map[i+1][j+1]<this.map[i][j]-1||this.map[i][j]==0)){
                            this.changeFlag=1;
                            this.map[i][j]=this.map[i+1][j+1]+1;
                        }
                    }
                }
            }
            if(this.changeFlag==1)
            {
                //changeFlag为1说明距离矩阵改变，需要回溯
                this.recurShortest();
            }
        }
        private move():number{
            //已经走在边界了，成功逃脱
            if(this.row==0||this.row==8||this.col==0||this.col==8){
                return -1;
            }
            let d1:number=this.map[this.row-1][this.col];//猫所处位置的上
            let d2:number=this.map[this.row+1][this.col];//猫所处位置的下
            let d3:number=this.map[this.row][this.col-1];//猫所处位置的左
            let d4:number=this.map[this.row][this.col+1];//猫所处位置的右
            let d5:number;
            let d6:number;
            if(this.row%2==0){
                //奇数行，左上左下
                d5=this.map[this.row-1][this.col-1];//猫所处位置的左上
                d6=this.map[this.row+1][this.col-1];//猫所处位置的左下
            }else{
                //偶数行，右上右下
                d5=this.map[this.row-1][this.col+1];//猫所处位置的右上
                d6=this.map[this.row+1][this.col+1];//猫所处位置的右上
            }
            let min:number=Math.min(d1,Math.min(d2,Math.min(d3,Math.min(d4,Math.min(d5,d6)))));
            let max:number=Math.max(d1,Math.max(d2,Math.max(d3,Math.max(d4,Math.max(d5,d6)))));
            if(max==0){//max为0说明已经被困住但是还可以走
                this.catchFlag=true;
                if(max==d1){
                    return 1;//上
                }else if(max==d2){
                    return 2;//下
                }else if(max==d3){
                    return 3;//左
                }else if(max==d4){
                    return 4;//右
                }else if(max==d5){
                    return 5;//左上或右上
                }else if(max==d6){
                    return 6;//左下或右下
                }
            }else if(max==-1){//max为-1说明六个方向都是障碍，即成功围住
                return 0;
            }else if(min==1){//min为1说明猫已经走到了边缘，可以逃脱
                return -1;
            }
            if(d1==-1){
                d1=100;
            }
            if(d2==-1){
                d2=100;
            }
            if(d3==-1){
                d3=100;
            }
            if(d4==-1){
                d4=100;
            }
            if(d5==-1){
                d5=100;
            }
            if(d6==-1){
                d6=100;
            }
            min=Math.min(d1,Math.min(d2,Math.min(d3,Math.min(d4,Math.min(d5,d6)))));
            if(min==d1){
                return 1;//上
            }else if(min==d2){
                return 2;//下
            }else if(min==d3){
                return 3;//左
            }else if(min==d4){
                return 4;//右
            }else if(min==d5){
                return 5;//左上或右上
            }else if(min==d6){
                return 6;//左下或右下
            }
        }
        public moveState():number{
            this.initMap();
            this.recurShortest();
            return this.move();
        }
        public getFlag():boolean{
            return this.catchFlag;
        }
        public setFlag(flag:boolean):void{
            this.catchFlag=flag;
        }
    }
}